home *** CD-ROM | disk | FTP | other *** search
/ Aminet 32 / Aminet 32 (1999)(Schatztruhe)[!][Aug 1999].iso / Aminet / disk / misc / ADFlib.lha / Lib / adf_disk.c < prev    next >
C/C++ Source or Header  |  1999-05-09  |  9KB  |  403 lines

  1. /*
  2.  *  ADF Library. (C) 1997-1998 Laurent Clevy
  3.  *
  4.  *  adf_disk.c
  5.  *
  6.  * logical disk/volume code
  7.  */
  8.  
  9. #include <limits.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12.  
  13. #include "adf_str.h"
  14. #include "adf_disk.h"
  15. #include "adf_raw.h"
  16. #include "adf_hd.h"
  17. #include "adf_bitm.h"
  18. #include "adf_util.h"
  19. #include "adf_nativ.h"
  20. #include "adf_dump.h"
  21. #include "adf_err.h"
  22. #include "adf_cache.h"
  23.  
  24. extern struct Env adfEnv;
  25.  
  26. unsigned long bitMask[32] = { 
  27.     0x1, 0x2, 0x4, 0x8,
  28.     0x10, 0x20, 0x40, 0x80,
  29.     0x100, 0x200, 0x400, 0x800,
  30.     0x1000, 0x2000, 0x4000, 0x8000,
  31.     0x10000, 0x20000, 0x40000, 0x80000,
  32.     0x100000, 0x200000, 0x400000, 0x800000,
  33.     0x1000000, 0x2000000, 0x4000000, 0x8000000,
  34.     0x10000000, 0x20000000, 0x40000000, 0x80000000 };
  35.  
  36.  
  37. RETCODE adfInstallBootBlock(struct Volume *vol, unsigned char* code)
  38. {
  39.     int i;
  40.     struct bBootBlock boot;
  41.  
  42.     if (vol->dev->devType!=DEVTYPE_FLOPDD && vol->dev->devType!=DEVTYPE_FLOPHD)
  43.         return RC_ERROR;
  44.  
  45.     if (adfReadBootBlock(vol, &boot)!=RC_OK)
  46.         return RC_ERROR;
  47.  
  48.     boot.rootBlock = 880;
  49.     for(i=0; i<1024-12; i++)         /* bootcode */
  50.         boot.data[i] = code[i+12];
  51.  
  52.     if (adfWriteBootBlock(vol, &boot)!=RC_OK)
  53.         return RC_ERROR;
  54.  
  55.     vol->bootCode = TRUE;
  56.  
  57.     return RC_OK;
  58. }
  59.  
  60.  
  61. /*
  62.  * isSectNumValid
  63.  *
  64.  */
  65. BOOL isSectNumValid(struct Volume *vol, SECTNUM nSect)
  66. {
  67.     return (vol->firstBlock<=nSect && nSect<=vol->lastBlock);
  68. }    
  69.     
  70.  
  71.  
  72. /*
  73.  * adfVolumeInfo
  74.  *
  75.  */
  76. void adfVolumeInfo(struct Volume *vol)
  77. {
  78.     struct bRootBlock root;
  79.     char diskName[35];
  80.     int days,month,year;
  81.     
  82.     if (adfReadRootBlock(vol, vol->rootBlock, &root)!=RC_OK)
  83.         return;
  84.     
  85.     memset(diskName, 0, 35);
  86.     memcpy(diskName, root.diskName, root.nameLen);
  87.     
  88.     printf ("Name : %-30s\n",diskName);
  89.     printf ("Type : ");
  90.     switch(vol->dev->devType) {
  91.         case DEVTYPE_FLOPDD:
  92.             printf ("Floppy Double Density : 880 KBytes\n");
  93.             break;
  94.         case DEVTYPE_FLOPHD:
  95.             printf ("Floppy High Density : 1760 KBytes\n");
  96.             break;
  97.         case DEVTYPE_HARDDISK:
  98.             printf ("Hard Disk partition : %3.1f KBytes\n", 
  99.                 (vol->lastBlock - vol->firstBlock +1) * 512.0/1024.0);
  100.             break;
  101.         case DEVTYPE_HARDFILE:
  102.             printf ("HardFile : %3.1f KBytes\n", 
  103.                 (vol->lastBlock - vol->firstBlock +1) * 512.0/1024.0);
  104.             break;
  105.         default:
  106.             printf ("Unknown devType!\n");
  107.     }
  108.     printf ("Filesystem : ");
  109.     printf("%s ",isFFS(vol->dosType) ? "FFS" : "OFS");
  110.     if (isINTL(vol->dosType))
  111.         printf ("INTL ");
  112.     if (isDIRCACHE(vol->dosType))
  113.         printf ("DIRCACHE ");
  114.     putchar('\n');
  115.  
  116.     printf("free blocks = %ld\n", adfCountFreeBlocks(vol));
  117.     if (vol->readOnly)
  118.         printf("Read only\n");
  119.     else
  120.         printf("Read/Write\n");
  121.      
  122.     /* created */
  123.     adfDays2Date(root.coDays, &year, &month, &days);
  124.     printf ("created %d/%02d/%02d %ld:%02ld:%02ld\n",days,month,year,
  125.         root.coMins/60,root.coMins%60,root.coTicks/50);    
  126.     adfDays2Date(root.days, &year, &month, &days);
  127.     printf ("last access %d/%02d/%02d %ld:%02ld:%02ld,   ",days,month,year,
  128.         root.mins/60,root.mins%60,root.ticks/50);    
  129.     adfDays2Date(root.cDays, &year, &month, &days);
  130.     printf ("%d/%02d/%02d %ld:%02ld:%02ld\n",days,month,year,
  131.         root.cMins/60,root.cMins%60,root.cTicks/50);    
  132. }
  133.  
  134.  
  135.  
  136. /*
  137.  * adfMount
  138.  *
  139.  * 
  140.  */
  141. struct Volume* adfMount( struct Device *dev, int nPart, BOOL readOnly )
  142. {
  143.     long nBlock;
  144.     struct bRootBlock root;
  145.     struct bBootBlock boot;
  146.     struct Volume* vol;
  147.  
  148.     if (dev==NULL || nPart<nPart || nPart >= dev->nVol) {
  149.         (*adfEnv.eFct)("adfMount : invalid parameter(s)");
  150.         return NULL;
  151.     }
  152.  
  153.     vol = dev->volList[nPart];
  154.     vol->dev = dev;
  155.     vol->mounted = TRUE;
  156.  
  157. /*printf("first=%ld last=%ld root=%ld\n",vol->firstBlock,
  158.  vol->lastBlock, vol->rootBlock);
  159. */
  160.     if (adfReadBootBlock(vol, &boot)!=RC_OK) {
  161.         (*adfEnv.wFct)("adfMount : BootBlock invalid");
  162.         return NULL;
  163.     }       
  164.     
  165.     vol->dosType = boot.dosType[3];
  166.     if (isFFS(vol->dosType))
  167.         vol->datablockSize=512;
  168.     else
  169.         vol->datablockSize=488;
  170.  
  171.     if (dev->readOnly /*|| isDIRCACHE(vol->dosType)*/)
  172.        vol->readOnly = TRUE;
  173.     else
  174.        vol->readOnly = readOnly;
  175.            
  176.     if (adfReadRootBlock(vol, vol->rootBlock, &root)!=RC_OK) {
  177.         (*adfEnv.wFct)("adfMount : RootBlock invalid");       
  178.         return NULL;
  179.     }
  180.  
  181.     nBlock = vol->lastBlock - vol->firstBlock +1 - 2;
  182.  
  183.     adfReadBitmap( vol, nBlock, &root );
  184.     vol->curDirPtr = vol->rootBlock;
  185.  
  186.     return( vol );
  187. }
  188.  
  189.  
  190. /*
  191. *
  192. * adfUnMount
  193. *
  194. * free bitmap structures
  195. * free current dir
  196. */
  197. void adfUnMount(struct Volume *vol)
  198. {
  199.     if (!vol) {
  200.         (*adfEnv.eFct)("adfUnMount : vol is null");
  201.         return;
  202.     }
  203.  
  204.     adfFreeBitmap(vol);
  205.  
  206.     vol->mounted = FALSE;
  207.     
  208. }
  209.  
  210.  
  211.  
  212. /*
  213.  * adfCreateVol
  214.  *
  215.  * 
  216.  */
  217. struct Volume* adfCreateVol( struct Device* dev, long start, long len, 
  218.     char* volName, int volType )
  219. {
  220.     struct bBootBlock boot;
  221.     struct bRootBlock root;
  222. //    struct bDirCacheBlock dirc;
  223.     SECTNUM blkList[2];
  224.     struct Volume* vol;
  225.     int nlen;
  226.  
  227.     vol=(struct Volume*)malloc(sizeof(struct Volume));
  228.     if (!vol) { 
  229.         (*adfEnv.eFct)("adfCreateVol : malloc vol");
  230.         return NULL;
  231.     }
  232.     
  233.     vol->dev = dev;
  234.     vol->firstBlock = (dev->heads * dev->sectors)*start;
  235.     vol->lastBlock = (vol->firstBlock + (dev->heads * dev->sectors)*len)-1;
  236.     vol->rootBlock = (vol->lastBlock - vol->firstBlock+1)/2;
  237. /*printf("first=%ld last=%ld root=%ld\n",vol->firstBlock,
  238.  vol->lastBlock, vol->rootBlock);
  239. */
  240.     vol->curDirPtr = vol->rootBlock;
  241.  
  242.     vol->readOnly = dev->readOnly;
  243.  
  244.     vol->mounted = TRUE;
  245.  
  246.     nlen = min( MAXNAMELEN, strlen(volName) );
  247.     vol->volName = (char*)malloc(nlen+1);
  248.     if (!vol->volName) { 
  249.         (*adfEnv.eFct)("adfCreateVol : malloc");
  250.         free(vol); return NULL;
  251.     }
  252.     memcpy(vol->volName, volName, nlen);
  253.     vol->volName[nlen]='\0';
  254.  
  255.     memset(&boot, 0, 1024);
  256.     boot.dosType[3] = volType;
  257. /*printf("first=%d last=%d\n", vol->firstBlock, vol->lastBlock);
  258. printf("name=%s root=%d\n", vol->volName, vol->rootBlock);
  259. */
  260.     if (adfWriteBootBlock(vol, &boot)!=RC_OK) {
  261.         free(vol->volName); free(vol);
  262.         return NULL;
  263.     }
  264.  
  265.     if (adfCreateBitmap( vol )!=RC_OK) {
  266.         free(vol->volName); free(vol);
  267.         return NULL;
  268.     }
  269. //puts("22");
  270. /*for(i=0; i<127; i++)
  271. printf("%3d %x, ",i,vol->bitmapTable[0]->map[i]);
  272. */
  273.     if ( isDIRCACHE(volType) )
  274.         adfGetFreeBlocks( vol, 2, blkList );
  275.     else
  276.         adfGetFreeBlocks( vol, 1, blkList );
  277.  
  278.  
  279. /*printf("[0]=%d [1]=%d\n",blkList[0],blkList[1]);*/
  280.  
  281.     memset(&root, 0, LOGICAL_BLOCK_SIZE);
  282.  
  283.     if (strlen(volName)>MAXNAMELEN)
  284.         volName[MAXNAMELEN]='\0';
  285.     root.nameLen = strlen(volName);
  286.     memcpy(root.diskName,volName,root.nameLen);
  287.     adfTime2AmigaTime(adfGiveCurrentTime(),&(root.coDays),&(root.coMins),&(root.coTicks));
  288.  
  289.     /* dircache block */
  290.     if ( isDIRCACHE(volType) ) {
  291. //        vol->readOnly = TRUE;
  292.         root.extension = 0L;
  293.         root.secType = ST_ROOT; /* needed by adfCreateEmptyCache() */
  294.         adfCreateEmptyCache(vol, (struct bEntryBlock*)&root, blkList[1]);
  295.     }
  296.  
  297.     if (adfWriteRootBlock(vol, blkList[0], &root)!=RC_OK)
  298.         return NULL;
  299.  
  300.    /* fills root->bmPages[] and writes filled bitmapExtBlocks */
  301.     if (adfWriteNewBitmap(vol)!=RC_OK)
  302.         return NULL;
  303.  
  304.     if (adfUpdateBitmap(vol)!=RC_OK)
  305.         return NULL;
  306.  
  307.     /* will be managed by adfMount() later */
  308.     adfFreeBitmap(vol);
  309.  
  310.     vol->mounted = FALSE;
  311.  
  312.     return(vol);
  313. }
  314.  
  315.  
  316. /*-----*/
  317.  
  318. /*
  319.  * adfReadBlock
  320.  *
  321.  * read logical block
  322.  */
  323. RETCODE
  324. adfReadBlock(struct Volume* vol, long nSect, unsigned char* buf)
  325. {
  326.   /*    char strBuf[80];*/
  327.     long pSect;
  328.     struct nativeFunctions *nFct;
  329.     RETCODE rc;
  330.  
  331.     if (!vol->mounted) {
  332.         (*adfEnv.eFct)("the volume isn't mounted, adfReadBlock not possible");
  333.         return RC_ERROR;
  334.     }
  335.  
  336.     /* translate logical sect to physical sect */
  337.     pSect = nSect+vol->firstBlock;
  338. //printf("psect=%ld nsect=%ld\n",pSect,nSect);
  339. /*    sprintf(strBuf,"ReadBlock : accessing logical block #%ld", nSect);    
  340.     (*adfEnv.vFct)(strBuf);
  341. */
  342.     if (pSect<vol->firstBlock || pSect>vol->lastBlock) {
  343.         (*adfEnv.wFct)("adfReadBlock : nSect out of range");
  344.         
  345.     }
  346. //printf("pSect R =%ld\n",pSect);
  347.     nFct = adfEnv.nativeFct;
  348.     if (vol->dev->isNativeDev)
  349.         rc = (*nFct->adfNativeReadSector)(vol->dev, pSect, 512, buf);
  350.     else
  351.         rc = adfReadDumpSector(vol->dev, pSect, 512, buf);
  352. //printf("rc=%ld\n",rc);
  353.     if (rc!=RC_OK)
  354.         return RC_ERROR;
  355.     else
  356.         return RC_OK;
  357. }
  358.  
  359.  
  360. /*
  361.  * adfWriteBlock
  362.  *
  363.  */
  364. RETCODE adfWriteBlock(struct Volume* vol, long nSect, unsigned char *buf)
  365. {
  366.     long pSect;
  367.     struct nativeFunctions *nFct;
  368.     RETCODE rc;
  369.  
  370.     if (!vol->mounted) {
  371.         (*adfEnv.eFct)("the volume isn't mounted, adfWriteBlock not possible");
  372.         return RC_ERROR;
  373.     }
  374.  
  375.     if (vol->readOnly) {
  376.         (*adfEnv.wFct)("adfWriteBlock : can't write block, read only volume");
  377.         return RC_ERROR;
  378.     }
  379.  
  380.     pSect = nSect+vol->firstBlock;
  381. //printf("write nsect=%ld psect=%ld\n",nSect,pSect);
  382.  
  383.     if (pSect<vol->firstBlock || pSect>vol->lastBlock) {
  384.         (*adfEnv.wFct)("adfWriteBlock : nSect out of range");
  385.     }
  386.  
  387.     nFct = adfEnv.nativeFct;
  388. //printf("nativ=%d\n",vol->dev->isNativeDev);
  389.     if (vol->dev->isNativeDev)
  390.         rc = (*nFct->adfNativeWriteSector)(vol->dev, pSect, 512, buf);
  391.     else
  392.         rc = adfWriteDumpSector(vol->dev, pSect, 512, buf);
  393.  
  394.     if (rc!=RC_OK)
  395.         return RC_ERROR;
  396.     else
  397.         return RC_OK;
  398. }
  399.  
  400.  
  401.  
  402. /*#######################################################################################*/
  403.